package cn.edu.dutir.parser;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;

import org.xml.sax.InputSource;

import cn.edu.dutir.utility.Constants;

import com.aliasi.corpus.Handler;
import com.aliasi.corpus.InputSourceParser;
import com.aliasi.util.Streams;

public abstract class TextParser<H extends Handler> extends
		InputSourceParser<H> {
	private final String mMarker;
	private final String mCharset;
	private boolean mEndMarker;

	public TextParser(String mark) {
		this(mark, true);
	}

	public TextParser(String mark, boolean endMarker) {
		this(mark, Constants.DEFAULT_CHARSET, endMarker);
	}

	public TextParser(String mark, String charset) {
		this(mark, charset, true);
	}

	public TextParser(String mark, String charset, boolean endMarker) {
		mMarker = mark.toLowerCase();
		mCharset = charset;
		mEndMarker = endMarker;
	}

	@Override
	public void parse(InputSource inSrc) throws IOException {
		InputStream in = null;
		Reader reader = null;
		BufferedReader bufReader = null;
		try {
			reader = inSrc.getCharacterStream();
			if (reader == null) {
				in = inSrc.getByteStream();
				String encoding = inSrc.getEncoding();
				reader = (mCharset != null) ? new InputStreamReader(in,
						mCharset) : (encoding != null) ? new InputStreamReader(
						in, encoding) : new InputStreamReader(in);
			}
			bufReader = new BufferedReader(reader);
			String text = null;
			StringBuffer sb = new StringBuffer(Constants.DEFAULT_BUFFER_SIZE);
			while ((text = bufReader.readLine()) != null) {
				if (mEndMarker) {
					sb.append(text + Constants.NEWLINE);
				}
				if (text.toLowerCase().startsWith(mMarker)) {
					parseText(sb.toString());
					sb.setLength(0);
				}
				if (!mEndMarker) {
					sb.append(text + Constants.NEWLINE);
				}
			}

		} finally {
			Streams.closeReader(bufReader);
			Streams.closeReader(reader);
			Streams.closeInputStream(in);
		}
	}

	public abstract void parseText(String textObj);

	public abstract void close();
}
